<script setup lang="ts">
import { request } from '@/network/axios'
import type { CrystallographicPointGroup, PointGroupTree } from '@/types'
import { useEventListener } from '@vueuse/core'
import * as echarts from 'echarts'
import { onUnmounted, ref, useTemplateRef, watchEffect } from 'vue'
import { useRequest } from 'vue-hooks-plus'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
import LoadingOverlay from '../ui/LoadingOverlay.vue'

// 定义图表节点数据类型

const { t } = useI18n()
const router = useRouter()

// 接收要高亮的点群 ID
const { highlightGroupId } = defineProps<{ highlightGroupId?: string }>()

// 图表实例和容器引用（使用 Vue 3.5 的 useTemplateRef）
const chartContainer = useTemplateRef('chartContainer')
let chartInstance: echarts.ECharts | undefined = undefined

// 符号显示模式：Schoenflies 或 International
const symbolMode = ref<'schoenflies' | 'international'>('schoenflies')

// 获取数据 - 使用 useRequest
const { data: treeData, loading } = useRequest(() => request<PointGroupTree>('/symmetry/point-groups-tree'))

const getShadowColor = (color: string) => {
  // 如果是 hex 格式，转换为 rgba
  if (color.startsWith('#')) {
    const r = parseInt(color.slice(1, 3), 16)
    const g = parseInt(color.slice(3, 5), 16)
    const b = parseInt(color.slice(5, 7), 16)
    return `rgba(${r}, ${g}, ${b}, 0.5)`
  }
  return color
}

// 初始化图表
const initChart = () => {
  if (!chartContainer.value || !treeData.value) return

  chartInstance = echarts.getInstanceByDom(chartContainer.value) ?? echarts.init(chartContainer.value)

  const colors = ['#5470c6', '#91cc75']
  const highlightColor = colors[1]!
  const edgeColor = '#aaa'

  const { nodes, edges } = treeData.value

  // 按阶数分组创建层级布局
  const nodesByOrder = nodes.reduce<Map<number, CrystallographicPointGroup[]>>((acc, node) => {
    const group = acc.get(node.order)
    if (group) group.push(node)
    else acc.set(node.order, [node])
    return acc
  }, new Map())

  // 按阶数排序（从小到大）
  const sortedOrders = [...nodesByOrder.keys()].sort((a, b) => a - b)

  // 计算每个节点的位置（层级布局）
  const width = 1200
  const height = 120

  const nodesWithPosition = sortedOrders.flatMap((order, idx) => {
    const nodesInLayer = nodesByOrder.get(order)!
    return nodesInLayer.map((node, nodeIndex) => ({
      ...node,
      id: node.groupId,
      name: symbolMode.value === 'schoenflies' ? node.schoenflies : node.international,
      x: (width * (nodeIndex + 1)) / (nodesInLayer.length + 1),
      y: height * (sortedOrders.length - idx),
      value: order,
      isHighlighted: highlightGroupId === node.groupId
    }))
  })

  // 标记与高亮节点相关的边
  const edgesWithHighlight = edges.map(edge => ({
    ...edge,
    isHighlighted: highlightGroupId === edge.source || highlightGroupId === edge.target
  }))

  // 配置图表
  const option = {
    tooltip: {
      position: 'top',
      formatter: (params: echarts.DefaultLabelFormatterCallbackParams) => {
        if (params.dataType === 'node' && params.data) {
          const node = params.data as (typeof nodesWithPosition)[number]
          return `<div style="padding:8px;line-height:1.4;">
            <div style="font-weight:600;margin-bottom:6px;">${node.name}</div>
            <div style="font-size:12px;">Schoenflies: <b>${node.schoenflies}</b></div>
            <div style="font-size:12px;">International: <b>${node.international}</b></div>
            <div style="font-size:12px;">${t('symmetry.pointGroup.order')}: <b>${node.value}</b></div>
            <div style="font-size:12px;">${t('symmetry.pointGroup.crystalSystem')}: <b>${node.crystalSystem}</b></div>
            <div style="font-size:12px;">${t('symmetry.pointGroup.laueClass')}: <b>${node.laueClass}</b></div>
          </div>`
        } else if (params.dataType === 'edge' && params.data) {
          const edge = params.data as (typeof edgesWithHighlight)[number]
          return `<div style="padding:8px;line-height:1.4;">
            <div style="font-weight:600;margin-bottom:4px;">${t('components.pointGroupTree.subgroupRelation')}</div>
            <div style="font-size:12px;">${edge.source} → ${edge.target}</div>
            <div style="font-size:12px;">Index [G:H]: <b>${edge.index}</b></div>
          </div>`
        }
      }
    },
    series: [
      {
        type: 'graph' as const,
        data: nodesWithPosition.map(node => ({
          ...node,
          category: node.isHighlighted ? 1 : 0,
          symbolSize: node.isHighlighted ? Math.max(35, Math.min(80, 35 + Math.log(node.value) * 12)) : Math.max(20, Math.min(60, 20 + Math.log(node.value) * 10)),
          itemStyle: node.isHighlighted
            ? {
                borderWidth: 3,
                shadowBlur: 10,
                shadowColor: getShadowColor(highlightColor)
              }
            : undefined,
          label: {
            fontSize: node.isHighlighted ? 15 : 12,
            fontWeight: 'bold',
            show: true
          }
        })),
        edges: edgesWithHighlight.map(edge => ({
          ...edge,
          lineStyle: {
            color: edge.isHighlighted ? highlightColor : edgeColor,
            width: edge.isHighlighted ? 3 : edge.index === 2 ? 2 : 1,
            opacity: edge.isHighlighted ? 1 : 0.7
          }
        })),
        categories: [{ name: t('components.pointGroupTree.crystallographic') }, { name: t('components.pointGroupTree.highlighted') }],
        roam: true,
        emphasis: { focus: 'adjacency' }
      }
    ]
  }

  chartInstance.setOption(option)
  chartInstance.on('click', (params: echarts.ECElementEvent) => {
    if (params.dataType === 'node' && params.data) {
      const nodeData = params.data as (typeof nodesWithPosition)[number]
      router.push(`/point-groups/${nodeData.id}`)
    }
  })
}

watchEffect(() => {
  if (treeData.value && chartContainer.value) initChart()
})

useEventListener(window, 'resize', () => chartInstance?.resize())

onUnmounted(() => {
  chartInstance?.dispose()
  chartInstance = undefined
})
</script>

<template>
  <div class="card bg-base-100 border-base-300 border shadow-md">
    <LoadingOverlay v-if="loading" />

    <div class="card-body">
      <h2 class="card-title gap-4">
        {{ t('components.pointGroupTree.title') }}
        <div class="join join-horizontal">
          <button class="btn btn-sm join-item" :class="{ 'btn-primary': symbolMode === 'schoenflies' }" @click="symbolMode = 'schoenflies'">
            {{ t('components.pointGroupTree.symbolMode.schoenflies') }}
          </button>
          <button class="btn btn-sm join-item" :class="{ 'btn-primary': symbolMode === 'international' }" @click="symbolMode = 'international'">
            {{ t('components.pointGroupTree.symbolMode.international') }}
          </button>
        </div>
      </h2>

      <div v-if="treeData" ref="chartContainer" class="min-h-180"></div>
    </div>
  </div>
</template>
